import {
  createVNode,
  inject,
  render,
  type App,
  type Plugin,
  type VNode,
} from "vue";
import DaisyLoading from "./DaisyLoading.vue";

declare global {
  interface DaisyLoadingPlugin {
    showLoading(
      type?: "spinner" | "dots" | "ring" | "ball" | "bars" | "infinity",
      size?: "xs" | "sm" | "md" | "lg",
    ): void;
    hideLoading(): void;
    isLoading(): boolean;
  }
  interface DaisyPlugin {
    loading: DaisyLoadingPlugin;
  }
}

declare module "vue" {
  interface ComponentCustomProperties {
    $daisy: DaisyPlugin;
  }
}

const createContainer = () => {
  const container = document.createElement("div");
  container.id = "daisy-loading-container";
  container.className = "fixed top-1/2 left-1/2  w-0 h-0";
  document.body.appendChild(container);
  return container;
};
const renderLoading = (vnode: VNode | null) => {
  const container =
    document.getElementById("daisy-loading-container") || createContainer();
  render(vnode, container);
};

let loading = false;
const plugin: DaisyLoadingPlugin = {
  showLoading(
    type:
      | "spinner"
      | "dots"
      | "ring"
      | "ball"
      | "bars"
      | "infinity" = "spinner",
    size: "xs" | "sm" | "md" | "lg" = "lg",
  ) {
    loading = true;
    renderLoading(null);
    const vnode = createVNode(DaisyLoading, {
      type,
      size,
      onDestroy: () => {
        renderLoading(null);
      },
    });
    renderLoading(vnode);
  },
  hideLoading() {
    loading = false;
    renderLoading(null);
  },
  isLoading() {
    return loading;
  },
};

export const DaisyLoadingPlugin: Plugin = {
  install(app: App) {
    app.component("DaisyLoading", DaisyLoading);
    if (app.config.globalProperties.$daisy) {
      app.config.globalProperties.$daisy.loading = plugin;
    } else {
      const p: any = {
        loading: plugin,
      };
      app.config.globalProperties.$daisy = p;
    }

    const daisy = inject<DaisyPlugin>("daisy");
    if (daisy) {
      daisy.loading = plugin;
      app.provide("daisy", daisy);
    } else {
      app.provide("daisy", {
        loading: plugin,
      });
    }
  },
};

export function useDaisyLoading(): DaisyLoadingPlugin {
  const daisy = inject<DaisyPlugin>("daisy");
  if (!daisy) {
    console.warn("Daisy plugin not installed");
    return plugin;
  }
  return daisy.loading;
}
export function useDaisy(): DaisyPlugin | DaisyLoadingPlugin {
  const daisy = inject<DaisyPlugin>("daisy");
  if (!daisy) {
    console.warn("Daisy plugin not installed");
    return plugin;
  }
  return daisy;
}

export default DaisyLoadingPlugin;
